package com.yaodian100.ec.announcement.service.impl;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.impl.DomainServiceImpl;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.ec.announcement.entity.Announcement;
import com.yaodian100.ec.announcement.service.AnnouncementService;

/**
 * 耀點快報
 * 
 * @author apple.chang
 * 
 */
public class AnnouncementServiceImpl extends DomainServiceImpl<Announcement> implements AnnouncementService {

	/**
	 * 新增公告
	 */
	@Override
	@Transactional(readOnly = false)
	public Announcement saveOrUpdateAnnouncement(Announcement entity) throws CoreException {
		Announcement announcement = null;
		if (StringUtils.isBlank(entity.getTargetURL())) {
			// 将内容去除html code存入db
			String content = entity.getBody();
			entity.setBody(StringUtils.substring(com.yaodian100.core.common.utils.StringUtils.removeHTML(content, true), 0,
					100));
			announcement = getDao().save(entity);
			saveToFile(announcement.getId(), content);
		} else {
			announcement = getDao().save(entity);
		}
		return announcement;
	}

	/**
	 * 取得所有公告
	 */
	@Override
	public List<Announcement> getAnnouncementList(String[] sortOrder) throws CoreException {
		List<Announcement> announcementList = getDao().getList(null, sortOrder);
		return announcementList;
	}

	/**
	 * 取得目前可顯示公告
	 */
	@Override
	public List<Announcement> getVisibleAnnouncementList(int size) throws CoreException {
		ArrayList<String> type = new ArrayList<String>();
		type.add("MYYAODIAN");
		// type.add("COMMEND_GET_MONEY");
		// type.add("PREFERENTIAL");
		// type.add("SYSTEM_ANNOUNCEMENT");
		return getVisibleAnnouncementList(type, size);
	}

	/**
	 * 以開始日期、顯示順序、最後修改時間尤新到舊排序
	 */
	public List<Announcement> getMemberMessageList() {
		ArrayList<String> typeList = new ArrayList<String>();
		typeList.add(AnnouncementService.ANNOUNCEMENT_TYPE_MEMBER_MESSAGE);

		List<Announcement> announcementList = getVisibleAnnouncementList(typeList, -1);
		return announcementList;
	}

	/**
	 * 取得目前可顯示公告
	 */
	@Override
	public List<Announcement> getVisibleAnnouncementList(ArrayList<String> type, int size) throws CoreException {
		CommonCriteria crit = new CommonCriteria();
		crit.addEq("isDelete", "N");
		Date now = new Date();
		crit.addLe("startDate", now);
		crit.addGe("endDate", now);
		if (null != type && !type.isEmpty()) {
			crit.addIn("type", type);
		}
		List<Announcement> announcementList = getList(0, size, crit, DEFAULT_SORT_FOR_HQL);
		return announcementList;
	}

	@Override
	@Transactional(readOnly = false)
	public Announcement deleteAnnouncement(String announcementId) throws CoreException {
		CommonCriteria crit = new CommonCriteria();
		crit.addEq("id", Long.parseLong(announcementId));
		List<Announcement> anns = getList(0, -1, crit, null);
		if (anns.size() == 1) {
			Announcement ann = anns.get(0);
			ann.setIsDelete("Y");
			return getDao().update(ann);
		}
		return null;
	}

	@Override
	public Object[] getAnnouncementById(String announcementId) throws CoreException {
		Object[] obj = new Object[2];
		CommonCriteria crit = new CommonCriteria();
		crit.addEq("id", Long.parseLong(announcementId));
		List<Announcement> anns = getList(0, -1, crit, null);
		if (anns.size() == 1) {
			Announcement entity = anns.get(0);
			String content = readFromFile(entity.getId());
			obj[0] = entity;
			obj[1] = content;
			return obj;
		} else {
			return null;
		}
	}

	public Announcement getVisibleAnnouncementById(String announcementId) throws CoreException {
		CommonCriteria crit = new CommonCriteria();
		crit.addEq("id", Long.parseLong(announcementId));
		Date now = new Date();
		crit.addLe("startDate", now);
		crit.addGe("endDate", now);

		List<Announcement> anns = getList(0, -1, crit, null);
		if (anns.size() == 1) {
			Announcement entity = anns.get(0);
			String content = readFromFile(entity.getId());
			if (StringUtils.isNotBlank(content)) {
				entity.setBody(content);
			}
			return entity;
		} else {
			return null;
		}
	}

	/**
	 * 將公告内容儲存成檔案
	 * 
	 * @return
	 */
	void saveToFile(Long annId, String context) {
		try {
			String id = converInt(annId, 8);
			String filename = ServerValue.getMidHtmlPath() + "news/";
			FileUtils.forceMkdir(new File(filename + File.separator + id.substring(0, 4) + File.separator));
			File file = new File(filename + File.separator + id.substring(0, 4) + File.separator + annId + ".txt");
			FileUtils.writeStringToFile(file, context);
		} catch (IOException e) {
			logger.info("Announcement_saveToFile error :{}", e.toString());
		}
	}

	/**
	 * 將公告内容讀出
	 * 
	 * @return
	 */
	String readFromFile(Long annId) throws CoreException {
		StringBuffer context = new StringBuffer();
		try {
			String id = converInt(annId, 8);
			File aFile = new File(ServerValue.getMidHtmlPath() + "news" + File.separator + id.substring(0, 4)
					+ File.separator + annId + ".txt");
			if (aFile.isFile()) {
				FileReader fr = new FileReader(aFile);
				int ch;
				do {
					ch = fr.read();
					if (ch != -1) {
						context.append((char) ch);
					}
				} while (ch != -1);
				fr.close();
			}
		} catch (IOException e) {
			logger.info("Announcement_readFromFile error :{}", e.toString());
		}
		return context.toString();
	}

	/**
	 * 將 integer 轉為指定長度
	 * 
	 * @param value
	 * @param size
	 * @return
	 */
	private String converInt(Long value, int size) {
		StringBuffer sb = new StringBuffer();
		int div = 1;
		for (int i = 0; i < size; i++) {
			if ((value / div) % 10 == 0) {
				sb.insert(0, "0");
			} else {
				sb.insert(0, (value / div) % 10);
			}
			div = div * 10;
		}
		return sb.toString();
	}
}